package com.hp.bon.sgw.wh.channel.handler;

import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.core.channel.handler.IAsynCallHandler;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.bon.sgw.wh.Constants.AliParam;
import com.hp.bon.sgw.wh.service.WHConfigService;
import com.hp.bon.sgw.wh.utils.SignUtilsImpl;
import com.hp.ocs.diameter.message.Message;

public class BalanceTaobaoHandler implements IAsynCallHandler {
	
	private static final Logger logger = LoggerFactory.getLogger(BalanceTaobaoHandler.class);
	private PrintStream printStream;
	private WHConfigService whConfigService;
	private String msgId;
	private String userNumber;
	private String instId;
	
	public BalanceTaobaoHandler(PrintStream printStream, String msgId,String userNumber,String instId, WHConfigService whConfigService){
		this.printStream = printStream;
		this.whConfigService = whConfigService;
		this.msgId = msgId;
		this.instId = instId;
		this.userNumber=userNumber;
	}
	
	@Override
	public void onCallResult(CallParam callParam) {
		XmlMessage ack = null;
		Object response = null;

		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}

		if (response == null) {
			logger.warn("callParam.getRetCode:"+ callParam.getRetCode());
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(),
					callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode(), callParam.getResultMsg());
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				logger.warn("unknown response type:"+ callParam.getResponse().getClass().getName());
			}
		}
		try {
			String respXML = TaobaoConvertResponseString(ack,callParam.getServiceResultCode());
			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();

			callParam.setResponse(ack);

			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库

				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}

			TaskManager.taskProcess(callParam);

		} catch (Exception e) {
			logger.info("Exception is :"+e);
		}
	}
	
	// 淘宝SOAP
	protected String TaobaoConvertResponseString(XmlMessage ack, int serviceResultCode) {
		
		logger.info("serviceResultCode " + serviceResultCode);
		logger.info("ack rc" + ack.getRC());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss") ;
		Date date = new Date(System.currentTimeMillis());
		StringBuilder sb = new StringBuilder();
		String priKeyValue = whConfigService.getValue(AliParam.remainPriKeyValue, "");
		String algorithm = whConfigService.getValue(AliParam.algorithm, "SHA1withRSA");
		StringBuilder respBody = new StringBuilder();
		String signTag = null;
		if (serviceResultCode == 0)   //充值成功
		{
			String value = null;
			
			String orinData = ack.getDATA();
			Document doc = null;
			try {
				doc = DocumentHelper.parseText(orinData);
				Element root = doc.getRootElement();

				Node node = root.selectSingleNode("//Service_Information/Total_Balance_Available");
				if (node != null) {
					value = node.getStringValue();
				}
			} catch (DocumentException e1) {
				logger.info("Document Exception :"+e1);
			}
			
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>")
					.append("<message>")
					.append("<head>")
					.append("<version>").append("1.0.1").append("</version>")
					.append("<instId>").append(instId).append("</instId>")
					.append("<type>RemainQueryRes</type>")
					.append("<msgId>").append(msgId).append("</msgId>")
					.append("<msgTime>").append(sdf.format(date)).append("</msgTime>")
					.append("<secId>").append("0002").append("</secId>")
					.append("</head>")
					.append("<body>")
					.append("<userNumber>").append(userNumber).append("</userNumber>")
					.append("<value>").append(value).append("</value>")
					.append("<bill>").append("0").append("</bill>")
					.append("<status>").append("SUCCESS").append("</status>")
					.append("<failedCode>").append("").append("</failedCode>")
					.append("<failedReason>").append("").append("</failedReason>")
					.append("</body>");
			
			//如果字段中有空格，要trim掉
			respBody.append(userNumber.trim()).append(value.trim()).append(0).append("SUCCESS").append("").append("");
			
			logger.info("respBody :"+respBody.toString());
			
			signTag = SignUtilsImpl.sign(respBody.toString(), priKeyValue, algorithm ,"UTF-8");
			
			logger.info("signTag :"+signTag);
			
			logger.info("signTag :"+signTag);
			
			sb.append("<signTag>").append(signTag).append("</signTag>")
			.append("</message>") ;
			
			logger.info("response to taobao :"+sb.toString());
			
			return sb.toString();
		}else if (serviceResultCode == 501||serviceResultCode == 508||serviceResultCode == 531)   //手机号不存在
		{
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>")
					.append("<message>")
					.append("<head>")
					.append("<version>").append("1.0.1").append("</version>")
					.append("<instId>").append(instId).append("</instId>")
					.append("<type>RemainQueryRes</type>")
					.append("<msgId>").append(msgId).append("</msgId>")
					.append("<msgTime>").append(sdf.format(date)).append("</msgTime>")
					.append("<secId>").append("0002").append("</secId>")
					.append("</head>")
					.append("<body>")
					.append("<userNumber>").append(userNumber).append("</userNumber>")
					.append("<value>").append("").append("</value>")
					.append("<bill>").append("").append("</bill>")
					.append("<status>").append("FAILED").append("</status>")
					.append("<failedCode>").append("0701").append("</failedCode>")
					.append("<failedReason>").append("手机号不存在").append("</failedReason>")
					.append("</body>");
			
			//如果字段中有空格，要trim掉
			respBody.append(userNumber.trim()).append("").append("").append("FAILED").append("0701").append("手机号不存在");
			
			logger.info("respBody :"+respBody.toString());
			
			signTag = SignUtilsImpl.sign(respBody.toString(), priKeyValue, algorithm ,"UTF-8");
			
			logger.info("signTag :"+signTag);
			
			sb.append("<signTag>").append(signTag).append("</signTag>")
			   .append("</message>") ;
			
			logger.info("response to taobao :"+sb.toString());
			
			return sb.toString();
		}else{
    		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>")
    				.append("<message>")
    				.append("<head>")
    				.append("<version>").append("1.0.1").append("</version>")
    				.append("<instId>").append(instId).append("</instId>")
    				.append("<type>RemainQueryRes</type>")
    				.append("<msgId>").append(msgId).append("</msgId>")
    				.append("<msgTime>").append(sdf.format(date)).append("</msgTime>")
    				.append("<secId>").append("0002").append("</secId>")
    				.append("</head>")
    				.append("<body>")
    				.append("<userNumber>").append(userNumber).append("</userNumber>")
    				.append("<value>").append("").append("</value>")
    				.append("<bill>").append("").append("</bill>")
    				.append("<status>").append("FAILED").append("</status>");
			if("11203".equals(ack.getRC())){
				sb.append("<failedCode>").append("0703").append("</failedCode>");
				sb.append("<failedReason>").append("系统处理超时").append("</failedReason>");
			}else{
				sb.append("<failedCode>").append("9999").append("</failedCode>");
				sb.append("<failedReason>").append("未知错误").append("</failedReason>");
			}
    				
    		sb.append("</body>");
    		
    		//如果字段中有空格，要trim掉
    		if("11203".equals(ack.getRC())){
    			respBody.append(userNumber).append("").append("").append("FAILED").append("0703").append("系统处理超时");
			}else{
				respBody.append(userNumber).append("").append("").append("FAILED").append("9999").append("未知错误");
			}
    		
    		logger.info("respBody :"+respBody.toString());
    		
    		signTag = SignUtilsImpl.sign(respBody.toString(), priKeyValue, algorithm ,"UTF-8");
    		
    		logger.info("signTag :"+signTag);
    		
    		sb.append("<signTag>").append(signTag).append("</signTag>").append("</message>") ;
		    		
    		logger.info("response to taobao :"+sb.toString());
    		
			return sb.toString();
		}
		
	}
	
	@Override
	public int getProtocolType() {
		return 0;
	}

}
